package com.api.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.api.config.RedisConstant;
import com.api.config.RedisService;
import com.api.entity.MsgTemplate;
import com.api.entity.SmsRecord;
import com.api.entity.User;
import com.api.log.Log;
import com.api.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import static com.api.entity.table.SmsRecordTableDef.SMS_RECORD;
import static com.api.entity.table.UserTableDef.USER;


/**
 * 短信验证码管理
 * @Description: 短信验证码管理
 * @Author: yangshfieng
 * @CreateDate: 2024/2/23
 */

@Slf4j
@Validated
@RestController
@RequestMapping("/sms")
public class SmsCodeController extends BaseController {

    @Autowired
    RedisService redisService;


    /**
     * 获取短信验证码
     * 接口：/sms/getCode
     * @param codeType  验证码类型： 1001.用户注册  1002.用户登录 1003.修改密码
     * @param userTele  登录手机号
     * @return
     */
    @Log("获取验证码")
    @RequestMapping("/getCode")
    public Result getCode(@Valid @NotNull(message = "非法请求") Integer codeType, @NotBlank(message = "手机号不能为空") String userTele){
        String key = "";
        User user = null;
        Long userId = null;
        long count = SmsRecord.create().select(SMS_RECORD.ID).where(SmsRecord::getTele).eq(userTele).and(SmsRecord::getCodeType).eq(codeType).and(SmsRecord::getCreateTime).gt(DateUtil.today()).count();
        if(count>=6){
            return Result.err("当日短信使用次数已达上限");
        }
        //验证码类型： 1001.用户注册  1002.用户登录 1003.验证码密码找回 1004.更换手机号 1005.用户注销
        switch (codeType){
            case 1001://1001.用户注册
                key = RedisConstant.USER_TELE_CODE_REGISTER + userTele;
                if(redisService.hasKey(key)){
                    if(redisService.getExpire(key)>240L){
                        return Result.err("60秒之内只允许获取一次");
                    }
                }
                user = User.create().select(USER.ALL_COLUMNS).where(User::getUserTele).eq(userTele).and(User::getStatus).gt(0).one();
                if(null != user){
                    return Result.err("当前手机号已注册，请勿重复注册");
                }
                break;
            case 1002://1002.用户登录
                key = RedisConstant.USER_TELE_CODE_LOGIN + userTele;
                if(redisService.hasKey(key)){
                    if(redisService.getExpire(key)>240L){
                        return Result.err("60秒之内只允许获取一次");
                    }
                }
                user = User.create().select(USER.ALL_COLUMNS).where(User::getUserTele).eq(userTele).and(User::getStatus).gt(0).one();
                if(null == user){
                    return Result.err("当前手机号未注册，请先注册");
                }
                if(null != user.getStatus() && user.getStatus() != 1){
                    return Result.err("当前账户状态异常，不允许操作");
                }
                break;
            case 1003://1003.验证码密码找回
                key = RedisConstant.USER_TELE_CODE_RESETPWD + userTele;
                if(redisService.hasKey(key)){
                    if(redisService.getExpire(key)>240L){
                        return Result.err("60秒之内只允许获取一次");
                    }
                }
                user = User.create().select(USER.ALL_COLUMNS).where(User::getUserTele).eq(userTele).and(User::getStatus).gt(0).one();
                if(null == user || (null != user && null != user.getStatus() && user.getStatus() != 1)){
                    return Result.err("当前账户状态异常，不允许操作");
                }
                break;
            case 1004://1004.更换手机号
                key = RedisConstant.USER_TELE_CODE_CHANGE + userTele;
                if(redisService.hasKey(key)){
                    if(redisService.getExpire(key)>240L){
                        return Result.err("60秒之内只允许获取一次");
                    }
                }
                user = User.create().select(USER.ALL_COLUMNS).where(User::getUserTele).eq(userTele).and(User::getStatus).gt(0).one();
                if(null == user || (null != user && null != user.getStatus() && user.getStatus() != 1)){
                    return Result.err("当前账户状态异常，不允许操作");
                }
                break;
            case 1005://1005.用户注销
                key = RedisConstant.USER_TELE_CODE_WRITTENOFF + userTele;
                if(redisService.hasKey(key)){
                    if(redisService.getExpire(key)>240L){
                        return Result.err("60秒之内只允许获取一次");
                    }
                }
                user = User.create().select(USER.ALL_COLUMNS).where(User::getUserTele).eq(userTele).and(User::getStatus).gt(0).one();
                if(null == user || (null != user && null != user.getStatus() && user.getStatus() != 1)){
                    return Result.err("当前账户状态异常，不允许操作");
                }
                break;
            default:
                return Result.err("非法请求");
        }
        MsgTemplate msg = MsgTemplate.create().where(MsgTemplate::getStatus).eq(1).and(MsgTemplate::getKind).eq(codeType).one();
        //生成验证码
        String code = RandomUtil.randomNumbers(5);
        //todo 调用第三发发送短信
//    @Column(value = "电话",ignore = true)
//    private String tele;
//
//    @Column(value = "参数1",ignore = true)
//    private String param1;
//
//    @Column(value = "参数2",ignore = true)
//    private String param2;
//
//    @Column(value = "参数3",ignore = true)
//    private String param3;
        msg.setTele(userTele);
        msg.setParam1(code);
        int i = 1; //UniCloudUtils.sendSms(msg);
        // 2.短信发送成功，插入短信记录，同时存入redis
        if(i>0) {
            if(null != user && null != user.getId()){
                userId = user.getId();
            }
            SmsRecord.create()
                    .setCodeType(codeType)
                    .setTele(userTele)
                    .setCode(code)
                    .setCreateId(userId)
                    .setCreateTime(new Date())
                    .save();
            //验证码 5分钟之内有效
            redisService.setCacheObject(key, code, 300L, TimeUnit.SECONDS);
            return Result.ok();
        }
        return Result.err("发送失败，请稍后再试");
    }
}
